﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.CPlusPlus;

namespace Сlassifier_Tool_For_OpenCV
{
    public partial class Test2 : Form
    {

        CvSize _winSize;
        CvSize _blockSize;
        CvSize _blockStride;
        CvSize _cellSize;
        int _nbins;
        int _aperature;
        int _winSigma;

        void SetSetting()
        {
            try
            {
                _winSize = new CvSize(Convert.ToInt32(textBox3.Text), Convert.ToInt32(textBox4.Text));
                _blockSize = new CvSize(Convert.ToInt32(textBox6.Text), Convert.ToInt32(textBox5.Text));
                _blockStride = new CvSize(Convert.ToInt32(textBox8.Text), Convert.ToInt32(textBox7.Text));
                _cellSize = new CvSize(Convert.ToInt32(textBox10.Text), Convert.ToInt32(textBox9.Text));
                _nbins = Convert.ToInt32(textBox11.Text);
                _aperature = Convert.ToInt32(textBox12.Text);
                _winSigma = Convert.ToInt32(textBox13.Text);

            }
            catch
            {

            }
        }

        public Test2()
        {
            InitializeComponent();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            SetSetting();
            if (File.Exists(textBox1.Text))
            {
                _hog = new HOGDescriptor(_winSize, _blockSize, _blockStride, _cellSize, _nbins, _aperature, _winSigma);
                var s = File.ReadAllText(textBox1.Text).Split(' ');
                var d = new float[s.Length];
                for (var i = 0; i < s.Length; i++)
                    d[i] = (float)Convert.ToDouble(s[i], CultureInfo.InvariantCulture);
                var posFile = Directory.GetFiles(textBox14.Text).ToList();
                var negFile = Directory.GetFiles(textBox2.Text).ToList();
                if (checkBox1.Checked)
                {
                    posFile.AddRange(Directory.GetDirectories(textBox14.Text).SelectMany(Directory.GetFiles));
                    negFile.AddRange(Directory.GetDirectories(textBox2.Text).SelectMany(Directory.GetFiles));
                }
                var pv = new List<double>();
                foreach (var variable in posFile)
                {
                    try
                    {


                        var h = HOG(variable);
                        double sum = 0;
                        for (var i = 0; i < h.Length; i++)
                            sum += h[i] * d[i];
                        pv.Add(sum + d[d.Length - 1]);
                    }
                    catch
                    {
                    }
                }
                var nv = new List<double>();
                foreach (var variable in negFile)
                {
                    try
                    {
                        var h = HOG(variable);
                        double sum = 0;
                        for (var i = 0; i < h.Length; i++)
                            sum += h[i] * d[i];
                        nv.Add(sum + d[d.Length - 1]);
                    }
                    catch
                    {
                    }
                }
                double maxi = -10;
                double maxp = 0;
                double maxn = 0;
                chart2.Series[0].Points.Clear();
                chart2.Series[1].Points.Clear();
                chart1.Series[0].Points.Clear();
                for (double thr = -5; thr < 5; thr += 0.01)
                {
                    var pe = pv.Count(variable => variable <= thr);
                    var ne = nv.Count(variable => variable > thr);
                    if (maxn * maxp <
                        (((posFile.Count - pe) * 100.0) / posFile.Count) * (((negFile.Count - ne) * 100.0) / negFile.Count))
                    {
                        maxp = ((posFile.Count - pe) * 100.0) / posFile.Count;
                        maxn = ((negFile.Count - ne) * 100.0) / negFile.Count;
                        maxi = thr;
                    }
                    chart1.Series[0].Points.AddXY(((pe) * 100.0) / posFile.Count,
                                                  ((ne) * 100.0) / negFile.Count);
                    chart2.Series[0].Points.AddXY(thr, ((posFile.Count - pe) * 100.0) / posFile.Count);
                    chart2.Series[1].Points.AddXY(thr, ((negFile.Count - ne) * 100.0) / negFile.Count);
                }
                label11.Text = maxi + " " + maxp + " / " + maxn;
            }
        }
        HOGDescriptor _hog;
        float[] HOG(string file)
        {
            var im = new IplImage(file, LoadMode.GrayScale);
            var image = new IplImage(_winSize, im.Depth, im.NChannels);
            Cv.Resize(im, image);
            var m = new Mat(image);
            var f = _hog.Compute(m);

            image.Dispose();
            m.Dispose();
            im.Dispose();
            return f;
        }

        private void Test2_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {

            if (openFileDialog2.ShowDialog() == DialogResult.OK)
                textBox1.Text = openFileDialog2.FileName;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                textBox1.Text = folderBrowserDialog1.SelectedPath;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                textBox1.Text = folderBrowserDialog1.SelectedPath;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (Directory.Exists("PosError")) Directory.Delete("PosError", true);
            Directory.CreateDirectory("PosError");
            if (Directory.Exists("NegError")) Directory.Delete("NegError", true);
            Directory.CreateDirectory("NegError");
            SetSetting();
            var pe = 0;
            if (File.Exists(textBox1.Text))
            {
                double threshold;
                double.TryParse(textBox15.Text, out threshold);
                _hog = new HOGDescriptor(_winSize, _blockSize, _blockStride, _cellSize, _nbins, _aperature, _winSigma);
                var s = File.ReadAllText(textBox1.Text).Split(' ');
                var d = new float[s.Length];
                for (var i = 0; i < s.Length; i++)
                    d[i] = (float)Convert.ToDouble(s[i], CultureInfo.InvariantCulture);
                var posFile = Directory.GetFiles(textBox14.Text).ToList();
                var negFile = Directory.GetFiles(textBox2.Text).ToList();
                if (checkBox1.Checked)
                {
                    posFile.AddRange(Directory.GetDirectories(textBox1.Text).SelectMany(Directory.GetFiles));
                    negFile.AddRange(Directory.GetDirectories(textBox2.Text).SelectMany(Directory.GetFiles));
                }

              

                foreach (var variable in posFile)
                {
                    try
                    {


                        var h = HOG(variable);
                        double sum = 0;
                        for (var i = 0; i < h.Length; i++)
                            sum += h[i] * d[i];
                        if (sum + d[d.Length - 1] < threshold)
                        {
                            pe++;
                            File.Copy(variable, "PosError\\" + Path.GetFileName(variable));
                            // (sum + d[d.Length - 1]).ToString()+" " + Guid.NewGuid().ToString() + ".jpg");

                        }
                    }
                    catch
                    {
                    }

                }
                foreach (var variable in negFile)
                {
                    try
                    {


                        var h = HOG(variable);
                        double sum = 0;
                        for (var i = 0; i < h.Length; i++)
                            sum += h[i] * d[i];
                        if (sum + d[d.Length - 1] >= threshold)
                        {
                            pe++;
                            File.Copy(variable, "NegError\\" + Path.GetFileName(variable));//(sum + d[d.Length - 1]).ToString()+" " + Guid.NewGuid().ToString() + ".jpg");
                        }
                    }
                    catch
                    {
                    }

                }


            }
        }
    }
}
